<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue 中组件数据通信 父子组件</title>
  <style>
    .header {
      height: 200px;
      background-color: #f60;
      color: #333;
      font-size: 24px;
    }
    .page {
      width: 200px;
      height: 100px;
    }

    .page-one {
      background-color: red;
    }

    .page-two {
      background-color: yellow;
    }
  </style>
</head>
<body>
  <div id="app">
    <!-- <p>{{ msg }}</p> -->
    <hs-header></hs-header>
    <!-- 父组件传值给子组件 -->
    <!-- <hs-header :receivemsg="msg" :items="lists"></hs-header> -->
    <hs-header :receivemsg="msg" @getdata="getSonData"></hs-header>
    <div class="show">
      从子组件中传递过来大数据：
      {{ sonData }}
    </div>
    <!-- 传值类型验证 -->
    <!-- <hs-header :receivemsg="msg" :items="lists2"></hs-header> -->
    <!-- <hs-test-data></hs-test-data>
    <hs-test-data></hs-test-data>
    <hs-test-data></hs-test-data> -->
    <div>
      <button type="button" @click="currentview='home'">主页</button>
      <button type="button" @click="currentview='news'">新闻</button>
      <!-- 动态组件 -->
      <component :is="currentview"></component>
    </div>
  </div>
  <!-- 1. 声明组件 -->
  <template id="hs_header">
    <div class="header">
      <h3>{{ msg }}</h3>
      <h2>{{ receivemsg }}</h2>
      <ul>
        <li v-for="item in items" :key="item.id">{{ item.id }}:{{ item.name }}</li>
      </ul>
      <button type="button" @click="postParent">子组件向父组件传值</button>
    </div>
  </template>
  <!-- 2. 动态切换组件 -->
  <template id="home">
    <div class="page page-one">
      这是主页
    </div>
  </template>
  <template id="news">
    <div class="page page-two">
      这是新闻页
    </div>
  </template>

  <!-- 用来测试data为什么返回一个函数 -->
  <template id="test_data">
    <div style="background-color: red;color: #FFF;">
      <h1>按钮被点击了 {{ count }} 次</h1>
      <button type="button" @click="add">点击增加</button>
    </div>
  </template>
</body>
<script src="./src/vue.js"></script>
<script>
  let obj = { count : 0 };
  const vm = new Vue({
    el: '#app',
    data: {
      msg: '这是Vue实例对象中data属性中的msg的值',
      currentview: 'home',
      lists: [
        {id:1, name: '刘备'},
        {id:2, name: '关羽'},
        {id:3, name: '张飞'},
      ],
      lists2: {},
      sonData: '这是用来显示从子组件传递过来的数据'
    },
    methods: {
      getSonData(msg){
        console.log('这是从子组件中传递过来的数据:', msg);
        this.sonData = msg;
      }
    },
    components: {
      home: {
        template: '#home'
      },
      news: {
        template: '#news'
      },
      hsHeader: {
        template: '#hs_header',
        // data: function() { }
        data(){//组件中的data 必须这种方式书写
          return {
            msg: '这是组件中的msg数据的值'
          }
        },
        // 通过属性 props 子组件接收从父组件传递过来的数据
        // props 是一个数组容器
        // props 的普通用法
        // props: ['receivemsg', 'items'],
        // 带类型验证的props用法
        props: {
          // 基础数据类型的检验
          receivemsg: String,
          items: Array,
          // 多种数据类型
          types: [String, Array, Object],
          // 必须且是String
          sTypes: {
            type: String,
            require: true
          },
          // 带默认值
          defaultVal: {
            type: Number,
            default: 100
          }
        },
        mounted() {
          console.log('组件已完成挂载!!!');
          console.log('this:',this.msg);
        },
        methods: {
          postParent(){
            // emit 提交
            // $emit(父组件的事件-回调事件, 传递的数据)
            this.$emit('getdata', this.msg);
          }
        },
        computed: {

        }
      },
      hsTestData: {
        template: '#test_data',
        // ES5 的正常写法
        // data: function(){
        //   return {
        //     count: 0
        //   }
        // }
        data: function(){
          return obj; //{}
        },
        methods: {
          add(){
            this.count ++;
          }
        },
      }
    }
  });

  // 如果想不明白 为啥 obj = { }   return obj 和 return {}不一样
  // 今天需要你把下面的代码想明白 
  // 这是跟 函数解析 有关系系的
  const obj_val = { num : 10};
  function read(){
    return obj_val;
  }

  // const 可乐 = { name: 百事, id: 1000001}
  // drink(){ retrun 可乐 }
  // li = drink() yang = drink()
  const obj1 = read();
  const obj2 = read();
  const obj3 = read();

  obj2.num = 99;
  console.log(obj1);
  console.log(obj2);
  console.log(obj3);
  // 打印的结果都是 { num: 99 }
  function read2(){
    return {
      num: 10
    };
  }

  const obj4 = read2();
  const obj5 = read2();
  const obj6 = read2();
  obj5.num = 99;
  console.log(obj4);//{ num: 10 }
  console.log(obj5);//99
  console.log(obj6);//10

  // obj1 obj2 obj3 会一起改变，是因为它们3引用的都是obj的变量地址，它们的数据都是绑定在obj的上的变量，一变全变
  // obj4 obj5 obj6 不会变，改谁谁变，是因为返回的是变量地址不一样，都指向各自新生成了一个对象地址在返回出去，所以一变不会全变。



</script>
</html>